package cn.org.donald.service.impl;

import cn.org.donald.base.ServiceException;
import cn.org.donald.mapper.RoleMapper;
import cn.org.donald.mapper.UserMapper;
import cn.org.donald.mapper.UserRoleMapper;
import cn.org.donald.pojo.entity.Role;
import cn.org.donald.pojo.entity.User;
import cn.org.donald.pojo.entity.UserRole;
import cn.org.donald.security.body.AuthorizationInfo;
import cn.org.donald.service.UserService;
import cn.org.donald.util.CryPtoUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * @author : Donald
 * @since : 2021/3/16 16:56
 */
@Service
public class UserServiceImpl implements UserService {

    @Resource
    private UserMapper userMapper;

    @Resource
    private RoleMapper roleMapper;

    @Resource
    private UserRoleMapper userRoleMapper;


    @Resource
    private RedisTemplate<String,AuthorizationInfo> redisTemplate;

    @Override
    public String login(Map<String, String> map) {
        String userName = map.get("userName");
        String password = map.get("password");
        if (userName == null || "".equals(userName) || password == null || "".equals(password)) {
            throw new ServiceException("用户名和密码不能为空!");
        }
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_name",userName);
        User user = userMapper.selectOne(queryWrapper);
        if (user != null) {
            // 获取用户的随机盐和明文密码加密比对
            String salt = user.getSalt();
            try {
                String encodedText = CryPtoUtil.getEncodedText(password, salt);
                if (user.getPassword().equals(encodedText)) {
                    // TODO 登录成功, 获取用户对应的权限放入redis(也可以在每次filter那里根据request的信息查一边数据库),key(authorization)-value(permissions and roles)
                    // 生成jwt
                    String authorization = CryPtoUtil.getAuthorization(userName, user.getId(), 1000 * 60 * 30L);

                    // 查询数据库获取角色、权限等
                    AuthorizationInfo authorizationInfo = new AuthorizationInfo();
                    QueryWrapper<UserRole> userRoleWrapper = new QueryWrapper<>();
                    userRoleWrapper.eq("user_id",user.getId());
                    List<UserRole> userRoles = userRoleMapper.selectList(userRoleWrapper);
                    List<Long> collect = userRoles.stream().map(UserRole::getRoleId).collect(Collectors.toList());
                    List<String> roleNames = roleMapper.selectBatchIds(collect).stream().map(Role::getRoleName).collect(Collectors.toList());
                    // 这里只添加了角色名,还可以添加权限名
                    authorizationInfo.addRoleNames(roleNames);
                    // 存入这个对象到时候拿出来可以直接用了
                    redisTemplate.opsForValue().set(authorization,authorizationInfo,32, TimeUnit.MINUTES);
                    return authorization;
                }
            } catch (Exception e) {
                e.printStackTrace();
                throw new ServiceException("登录异常!");
            }
        }
        throw new ServiceException("用户名或密码错误!");
    }
}
